# encoding = utf-8
# =====================================================
#   Copyright (C) 2019 All rights reserved.
#
#   filename : main.py
#   version  : 0.1
#   author   : gongzi.xu / 95168339@qq.com
#   date     : 2021/01/09
#   desc     :
# =====================================================
import json
from PyQt5.QtGui import QFont
from PyQt5 import QtGui

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5 import QtCore
from PyQt5.QtWidgets import *

from ui import Ui_main_ui as main_ui

from spider.reverse_geocoder import BdGeocoder
from spider.init_data import InitData

from render.gd_html_render import GaodeHtmlRender
from commons.utils import input_data_check

from templates.error_page import html_error_str

import webbrowser

import images_rc

CURRENT_VERSION = 0.21
SETTINGS_JSON_PATH = "settings.json"
CONFIG_JSON_PATH = "config.json"


class MainWindow(QtWidgets.QMainWindow, main_ui.Ui_MainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.init_sign()

        # 读取配置文件
        with open(SETTINGS_JSON_PATH, 'r', encoding='utf8')as f:
            self.settings_json = json.load(f)
        with open(CONFIG_JSON_PATH, 'r', encoding='utf8')as f:
            self.config_json = json.load(f)
        print('本地文件已全部加载完毕')
        self.init_menu_show()
        self.init_all_data()

    def init_menu_show(self):
        self.action_help.setVisible(self.settings_json.get('show_help_menu', False))
        self.action_aboutme.setVisible(self.settings_json.get("show_aboutme_menu", False))

    def init_all_data(self):
        # init 本地存储数据和云端配置数据
        self.init_data = InitData()
        self.init_data.cloud_settings_signal.connect(self.init_cloud_settings_data)
        self.init_data.finished_signal.connect(self.location_crawler_done)
        self.init_data.error_signal.connect(self.messageBox_error_warn)
        self.init_data.start()
        self.init_menu_show()

    def init_sign(self):

        self.tabWidget.currentChanged.connect(self.change_tab)

        self.action_help.triggered.connect(self.help)
        self.action_aboutme.triggered.connect(self.about)
        self.action_check_update.triggered.connect(self.check_update_version)
        self.search_button.clicked.connect(self.location_crawler)

    def init_cloud_settings_data(self, settings_json):
        self.settings_json = settings_json

    def closeEvent(self, QCloseEvent):
        reply = MyQMessageBox('温馨提示', '确定要退出应用程序吗？', '是', '否')
        if reply == 20180516:
            QCloseEvent.accept()
        else:
            QCloseEvent.ignore()

    def keyPressEvent(self, evt):
        if evt.key() == 16777268:  # F5
            self.pushButton_6.click()

    def location_crawler_done(self, _str):
        # 设置轨迹回放tab页可用
        self.tabWidget.setTabEnabled(1, True)

    def location_crawler(self):
        # 设置百度地图ak取用逻辑，优先本地，其次云端
        config_ak = self.config_json.get("ak")
        if config_ak not in [None, ""]:
            ak = config_ak
        elif "ak" in self.settings_json.keys():
            ak = self.settings_json.get("ak")
        else:
            ak = None
            self.messageBox_error_warn("当前没有可用的百度地图ak,需要到程序所在目录中的config.json中配置可用的ak!")
        # 清空当前表格中的结果
        for i in range(self.tableWidget.rowCount()):
            self.tableWidget.removeRow(0)
        points_str = self.textEdit.toPlainText()
        self.show_crawl_progress("")
        if points_str == "":
            self.messageBox_error_warn("你还没有输入轨迹数据哦！")
        else:
            is_input_right, warn_str = input_data_check(input_data_str=points_str)
            if not is_input_right:
                self.messageBox_error_warn(warn_str)
            else:
                self.crawler = BdGeocoder(points_str=points_str, ak=ak)
                # self.crawler.finished_signal.connect(self.insert2list)
                self.crawler.error_signal.connect(self.messageBox_error_warn)
                self.crawler.result_signal.connect(self.load_initial_data)
                self.crawler.progress_signal.connect(self.show_crawl_progress)
                self.crawler.finished_signal.connect(self.location_crawler_done)
                try:
                    # 开始之前，设置轨迹回放tab页面不可用，防止线程冲突导致的假死
                    self.tabWidget.setTabEnabled(1, False)
                    self.crawler.start()
                except:
                    # 设置轨迹回放tab页可用
                    self.tabWidget.setTabEnabled(1, True)
                    QMessageBox.information(self, "警告", "解析经纬度时遇到点问题，检查下是不是断网了呢？", QMessageBox.Yes)

    def messageBox_error_warn(self, error_str):
        QMessageBox.information(self, "错误警告", "%s" % error_str, QMessageBox.Yes)

    def show_crawl_progress(self, _str):
        if "done" in _str:
            self.label_progress.setVisible(False)
        else:
            self.label_progress.setVisible(True)
            self.label_progress.setText(_str)

    def show_html_progress(self, _str):

        if "done" in _str:
            self.label_html.setVisible(False)
        else:
            self.label_html.setVisible(True)
            self.label_html.setText(_str)

    def about(self):
        if "about_me_url" in self.settings_json.keys():
            reply = QMessageBox.information(self, "关于", "当前版本号：%s\n作者：gongli.xu \n需要访问作者的个人主页吗？" % CURRENT_VERSION,
                                            QMessageBox.No, QMessageBox.Yes)
            if reply == 20180516:
                webbrowser.open(self.settings_json.get("about_me_url"))
        else:

            QMessageBox.information(self, "关于", "当前版本号：%s\n作者：gongli.xu " % CURRENT_VERSION,
                                    QMessageBox.Yes)

    def check_update_version(self):
        if "latest_version" in self.settings_json.keys():
            latest_version = self.settings_json.get("latest_version")
            latest_version_release_url = self.settings_json.get("latest_version_release_url")
            if latest_version > CURRENT_VERSION and latest_version_release_url != "":
                reply = QMessageBox.information(self, "温馨提示", "发现新的版本，需要跳转到下载页面吗？", QMessageBox.No, QMessageBox.Yes)
                if reply == 20180516:
                    self.visit_latest_version_url(latest_version_release_url)
            else:
                QMessageBox.information(self, "温馨提示", "已经是最新版本了哦！", QMessageBox.Yes)
        else:
            QMessageBox.information(self, "温馨提示", "已经是最新版本了哦！", QMessageBox.Yes)

    def help(self):

        help_url = 'https://www.zhihu.com/people/yywh'
        if 'help_url' in self.settings_json.keys():
            help_url = self.settings_json.get("help_url")
        webbrowser.open(help_url)

    def visit_latest_version_url(self, latest_version_release_url):
        webbrowser.open(latest_version_release_url)

    def change_tab(self):

        if self.tabWidget.currentIndex() == 0:
            self.qframe.show()
            self.web_view.setHtml("")
        elif self.tabWidget.currentIndex() == 1:
            self.qframe.hide()
            # self.web_view.load(QUrl("render.html"))
            # 以下函数包含input_data校验

            points_str = self.textEdit.toPlainText()
            if points_str == "":
                self.messageBox_error_warn("你还没有输入轨迹数据哦！")
            else:
                is_input_right, warn_str = input_data_check(input_data_str=points_str)
                if not is_input_right:
                    self.messageBox_error_warn(warn_str)
                else:
                    self.gd_html_render = GaodeHtmlRender(points_str)
                    self.gd_html_render.result_signal.connect(self.show_html)
                    self.gd_html_render.progress_signal.connect(self.show_html_progress)
                    self.gd_html_render.start()

    # except Exception as e:
    #     self.messageBox_error_warn("好像哪里出错了，再试一下呢！错误详情:\n %s" % e)

    def show_html(self, html_str):
        try:
            self.web_view.setHtml(html_str)
        except Exception as e:
            self.web_view.setHtml(html_error_str.replace("错误详情", str(e)))

    def load_initial_data(self, location):
        row_count = self.tableWidget.rowCount()
        self.tableWidget.setRowCount(row_count + 1)
        position_time = location.get("position_time")
        if position_time is not None:
            item = QTableWidgetItem()
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 无法编辑
            item.setTextAlignment(Qt.AlignCenter)
            item.setText(position_time)
            self.tableWidget.setItem(row_count, 0, item)

        addressComponent = location['addressComponent']
        col_j = 1
        for k in ['province', 'city', 'district']:
            item = QTableWidgetItem()
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 无法编辑
            item.setTextAlignment(Qt.AlignCenter)
            item.setText(addressComponent.get(k))
            self.tableWidget.setItem(row_count, col_j, item)
            col_j += 1
            del item

        item = QTableWidgetItem()
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)  # 无法编辑
        item.setTextAlignment(Qt.AlignCenter)

        item.setText(location['formatted_address'])
        self.tableWidget.setItem(row_count, 4, item)


def MyQMessageBox(title, text, button1, button2=None):
    messageBox = QMessageBox()
    messageBox.setWindowTitle(title)
    messageBox.setText(text)
    if button2:
        messageBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        buttonY = messageBox.button(QMessageBox.Yes)
        buttonY.setText(button1)
        buttonN = messageBox.button(QMessageBox.No)
        buttonN.setText(button2)
    else:
        messageBox.setStandardButtons(QMessageBox.Yes)
        buttonY = messageBox.button(QMessageBox.Yes)
        buttonY.setText(button1)

    messageBox.exec_()
    if messageBox.clickedButton() == buttonY:
        return 20180516
    else:
        return 0


def show_loading():
    # 创建QSplashScreen对象实例
    splash = QtWidgets.QSplashScreen(QtGui.QPixmap(":/main/resources/search.png"))

    # 设置画面中的文字的字体
    splash.setFont(QFont('Microsoft YaHei UI', 10))
    # 显示画面
    splash.show()
    # 显示信息
    splash.showMessage("疯狂启动中", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.white)

    splash.finish(MainWindow)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = MainWindow()

    show_loading()  # 显示启动加载页面
    MainWindow.show()  # 当主界面显示后销毁启动画面
    sys.exit(app.exec_())
